package skiree.host.abetsy.service.core.vqq;

import cn.hutool.core.img.ColorUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.stereotype.Component;
import skiree.host.abetsy.dao.LocalCommentMapper;
import skiree.host.abetsy.dao.LocalEpisodeMapper;
import skiree.host.abetsy.model.LocalComment;
import skiree.host.abetsy.model.LocalEpisode;
import skiree.host.abetsy.service.core.Stratege;

import javax.annotation.Resource;
import java.awt.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Component
public class vQqProcess implements Stratege {

    @Resource
    private LocalEpisodeMapper localEpisodeMapper;

    @Resource
    private LocalCommentMapper localCommentMapper;

    @Override
    public void loadDanMu(LocalEpisode localEpisodeOld) {
        // 先检查localEpisode状态
        LocalEpisode localEpisode = localEpisodeMapper.selectById(localEpisodeOld.getId());
        if (localEpisode.getStatus().equals("init")) {
            localEpisode.setStatus("loading");
            localEpisode.setTime(new Date());
            localEpisodeMapper.updateById(localEpisode);
            String baseMark = "";
            Matcher matcherName = Pattern.compile("/([a-zA-Z0-9]+)\\.html").matcher(localEpisode.getUrl());
            if (matcherName.find()) {
                baseMark = matcherName.group(1);
            }
            List<String> baseUrl = getBaseUrl("https://dm.video.qq.com/barrage/base/" + baseMark, baseMark);
            for (String u : baseUrl) {
                getExtraDanMu("https://dm.video.qq.com/barrage/segment/" + u, localEpisode);
            }
        }
    }

    public List<String> getBaseUrl(String url, String baseMark) {
        List<String> list = new ArrayList<>();
        String result = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
        JSONObject jsonObject = JSONUtil.parseObj(JSONUtil.parse(result).getByPath("segment_index"));
        for (String key : jsonObject.keySet()) {
            JSONObject segmentObject = jsonObject.getJSONObject(key);
            String segmentName = segmentObject.getStr("segment_name");
            list.add(baseMark + "/" + segmentName);
        }
        return list;
    }

    public void getExtraDanMu(String url, LocalEpisode localEpisode) {
        List<LocalComment> comments = new ArrayList<>();
        String result = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
        JSONArray jsonArray = JSONUtil.parseArray(JSONUtil.parse(result).getByPath("barrage_list").toString());
        for (Object object : jsonArray) {
            JSONObject data = JSONUtil.parseObj(object.toString());
            String content = data.getStr("content");
            content = EmojiParser.removeAllEmojis(content);
            if (!content.isEmpty()) {
                Long offset = data.getLong("time_offset");
                BigDecimal start = new BigDecimal("0.00");
                if (offset != 0) {
                    start = new BigDecimal(offset).divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
                }
                String time = start.toString();
                String style = data.getStr("content_style");
                if (style.contains("gradient_colors")) {
                    JSONArray styleArray = JSONUtil.parseArray(JSONUtil.parse(style).getByPath("gradient_colors").toString());
                    Color color = ColorUtil.hexToColor(styleArray.get(0).toString().toUpperCase());
                    style = String.valueOf((color.getRed() * 256 * 256) + (color.getGreen() * 256) + color.getBlue());
                } else {
                    style = "16777215";
                }
                String position = "1";
                String userId = "[tx]";
                LocalComment localComment = new LocalComment();
                localComment.setEpisodeId(localEpisode.getId());
                localComment.setP(String.join(",", Arrays.asList(time, position, style, userId)));
                localComment.setM(content);
                localComment.setT(start);
                comments.add(localComment);
            }
        }
        // 时间相同的弹幕只保留三条
        comments = comments.stream()
                .collect(Collectors.groupingBy(LocalComment::getT))
                .values().stream()
                .flatMap(list -> list.stream().limit(3))
                .collect(Collectors.toList());
        localCommentMapper.insert(comments);
    }

    @Override
    public boolean supports(LocalEpisode localEpisode) {
        return localEpisode.getUrl().contains("v.qq.com");
    }

}
